package entity

import (
	"bytes"
	"errors"
	"fmt"
	"strings"
	"time"

	"shqsoft.cn/pasnj/base"

	//	log "github.com/sirupsen/logrus"
	"github.com/jinzhu/gorm"
)

// Position 职位
type Position struct {
	ID   int    `gorm:"primary_key;column:PONO"`
	Name string `gorm:"column:PONM;size:20"`
}

// TableName 职位表名
func (Position) TableName() string {
	return "T_USER_POSI"
}

// Position 职位
type PositionType struct {
	ID   int    `gorm:"primary_key;column:ID"`
	Name string `gorm:"column:NAME;"`
}

// TableName 职位表名
func (PositionType) TableName() string {
	return "T_USER_POSI_TYPE"
}

// Serial 序列
type Serial struct {
	ID   int    `gorm:"primary_key;column:SENO"`
	Name string `gorm:"column:SENM;size:20"`
}

// TableName Serial 序列表名
func (Serial) TableName() string {
	return "T_USER_SERI"
}

// User 用户
type User struct {
	ID             int          `gorm:"AUTO_INCREMENT;primary_key;column:ID"`
	No             string       `gorm:"column:SysUserID;size:10"`
	OrganizationID *int         `gorm:"column:OrganID"`
	Organization   Organization `gorm:"ForeignKey:OrganizationID"`
	Name           string       `gorm:"column:SysUserName;size:20"`
	Memo           string       `gorm:"column:SysUserMemo;size:500"`
	EMail          string       `gorm:"column:EMail;size:60"`
	Telephone      string       `gorm:"column:Telephone;size:30"`
	PositionID     int          `gorm:"column:Position"`
	Position       Position     `gorm:"ForeignKey:PositionID"`
	PositionTypeID int          `gorm:"column:PositionType"`
	PositionType   PositionType `gorm:"ForeignKey:PositionTypeID"`
	SerialID       int          `gorm:"column:Serial"`
	Serial         Serial       `gorm:"ForeignKey:SerialID"`
	Sex            string       `gorm:"column:SSEX;size:1"`
	SexCaption     string       `gorm:"-"`
	IsPublic       bool         `gorm:"column:ISPU"`
	RoleIds        string       `gorm:"column:RoleIds;size:100"`
	RoleCaptions   string       `gorm:"-"`
	Birthday       *time.Time   `gorm:"column:Birthday;type:date;"`
	NameCaption    string       `gorm:"-"`
	STATUS         string       `gorm:"column:STATUS"`
	STATUSCaption  string       `gorm:"-"`
	ISLSGHR        int          `gorm:"column:ISLSGHR"`
	YGXZ           string       `gorm:"column:YGXZ"`
	YGXZCaption    string       `gorm:"-"`
}

// TableName User用户表名
func (User) TableName() string {
	return "T_SysUser"
}

// BeforeCreate 插入前的触发器
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
	var count int
	err = tx.Model(User{}).Where("SysUserID=?", u.No).Count(&count).Error
	if err != nil {
		return err
	}
	if count > 0 {
		info := fmt.Sprintf("员工号%s已存在，请修改！", u.No)
		return errors.New(info)
	}
	if u.STATUS == "" {
		u.STATUS = "1"
	}
	// err = tx.Model(User{}).Where("SysUserName=?", u.Name).Count(&count).Error
	// if err != nil {
	// 	return err
	// }
	// if count > 0 {
	// 	info := fmt.Sprintf("员工名称【%s】已存在，请修改！", u.Name)
	// 	return errors.New(info)
	// }
	return
}

// BeforeUpdate 默认员工不允许,有认定关系，不允许更改部门
func (u *User) BeforeUpdate(tx *gorm.DB) (err error) {
	if u.ID == 0 {
		return errors.New("默认员工不允许修改！")
	}
	var oldUser User
	err = tx.First(&oldUser, u.ID).Error
	if err != nil {
		return err
	}
	u.STATUS = oldUser.STATUS
	base.CacheUser(u.ID, u.Name, *u.OrganizationID)
	// if *u.OrganizationID != *oldUser.OrganizationID {
	// 	msg, err := u.hasDivi(tx)
	// 	if err != nil {
	// 		return err
	// 	}
	// 	if msg != "" {
	// 		return fmt.Errorf("%s，不能直接修改其所属部门，请使用员工调动功能！", msg)
	// 	}
	// }
	return
}

// BeforeDelete 有认定关系，不允许删除员工
func (u *User) BeforeDelete(tx *gorm.DB) (err error) {
	if u.ID == 0 {
		return errors.New("默认员工不允许删除！")
	}
	msg, err := u.hasDivi(tx)
	if err != nil {
		return err
	}
	if msg != "" {
		return fmt.Errorf("%s，不能删除！", msg)
	}
	return
}

func (u *User) hasDivi(tx *gorm.DB) (msg string, err error) {
	var count int
	row := tx.Raw("select count(id) from T_COMP_ACCO_DIVI where emid=?", u.ID).Row()
	err = row.Scan(&count)
	if err != nil {
		return
	}
	if count > 0 {
		msg = "员工存在对公营销关系"
		return
	}
	row = tx.Raw("select count(id) from T_INDI_ACCO_DIVI where emid=?", u.ID).Row()
	err = row.Scan(&count)
	if err != nil {
		return
	}
	if count > 0 {
		msg = "员工存在储蓄营销关系"
		return
	}
	row = tx.Raw("select count(id) from T_INDI_FANA_DIVI where emid=?", u.ID).Row()
	err = row.Scan(&count)
	if err != nil {
		return
	}
	if count > 0 {
		msg = "员工存在个人理财营销关系"
		return
	}
	row = tx.Raw("select count(id) from T_INDI_LOAN_DIVI where emid=?", u.ID).Row()
	err = row.Scan(&count)
	if err != nil {
		return
	}
	if count > 0 {
		msg = "员工存在个贷营销关系"
		return
	}
	row = tx.Raw("select count(id) from T_INDI_LOAN_DIVI where emid=?", u.ID).Row()
	err = row.Scan(&count)
	if err != nil {
		return
	}
	if count > 0 {
		msg = "员工存在个贷营销关系"
		return
	}
	return
}

// AfterCreate 插入后的触发器
func (u *User) AfterCreate(tx *gorm.DB) (err error) {
	tx.Exec("UPDATE T_SysUser SET EMID=0")
	base.CacheUser(u.ID, u.Name, *u.OrganizationID)
	sql := "select ParentOrganID from V_ParentOrgan where OrganID=?"
	row := tx.Raw(sql, *u.OrganizationID).Row()
	var putid int
	row.Scan(&putid)
	if putid == 61 {
		tx.Exec("INSERT INTO t_UserRole(UserId,RoleId,IsAllowCommision,IsAllowProxy)VALUES(?,?,?,?)", u.ID, 112, 0, 0)
	}
	return
}

// AfterFind 选择男女
func (u *User) AfterFind() (err error) {
	if u.Sex == "1" {
		u.SexCaption = "男"
	} else {
		u.SexCaption = "女"
	}
	if u.STATUS == "1" {
		u.STATUSCaption = "正常"
	} else if u.STATUS == "2" {
		u.STATUSCaption = "已离职"
	} else {
		u.STATUSCaption = "已停用"
	}

	if u.YGXZ == "1" {
		u.YGXZCaption = "正式员工"
	} else if u.YGXZ == "2" {
		u.YGXZCaption = "虚拟员工"
	} else if u.YGXZ == "3" {
		u.YGXZCaption = "派遣员工"
	} else if u.YGXZ == "4" {
		u.YGXZCaption = "外包员工"
	} else if u.YGXZ == "5" {
		u.YGXZCaption = "其他员工"
	}
	if u.RoleIds != "" {
		ids := strings.Split(u.RoleIds, ",")
		sql := "select RoleName from t_Role where RoleID in (?)"
		rows, err := base.DB.Raw(sql, ids).Rows()
		if err != nil {
			return err
		}
		var buff bytes.Buffer
		defer rows.Close()
		for rows.Next() {
			var caption string
			rows.Scan(&caption)
			buff.WriteString(caption)
			buff.WriteString(",")
		}
		if l := buff.Len(); l > 0 {
			buff.Truncate(l - 1)
		}
		u.RoleCaptions = buff.String()
	}
	u.NameCaption = u.Organization.Name + "-" + u.Name
	return
}

// PositionEF 返回一个机构体
func PositionEF() base.EntityFunc {
	return func() interface{} {
		entity := Position{}
		return &entity
	}
}

// PositionESF 返回一个机构体数组
func PositionESF() base.EntitiesFunc {
	return func() interface{} {
		var entities []Position
		return &entities
	}
}

func PositionTypeEF() base.EntityFunc {
	return func() interface{} {
		entity := PositionType{}
		return &entity
	}
}

// PositionESF 返回一个机构体数组
func PositionTypeESF() base.EntitiesFunc {
	return func() interface{} {
		var entities []PositionType
		return &entities
	}
}
func SerialEF() base.EntityFunc {
	return func() interface{} {
		entity := Serial{}
		return &entity
	}
}
func SerialESF() base.EntitiesFunc {
	return func() interface{} {
		var entities []Serial
		return &entities
	}
}
func UserEF() base.EntityFunc {
	return func() interface{} {
		entity := User{}
		return &entity
	}
}
func UserESF() base.EntitiesFunc {
	return func() interface{} {
		var entities []User
		return &entities
	}
}

func init() {
	base.DaoPoolObj.Put("Position", base.NewDefaultDao(PositionEF(), PositionESF(), nil))
	base.DaoPoolObj.Put("Serial", base.NewDefaultDao(SerialEF(), SerialESF(), nil))
	base.DaoPoolObj.Put("PositionType", base.NewDefaultDao(PositionTypeEF(), PositionTypeESF(), nil))
	relationship := []string{"Organization", "Position", "Serial", "PositionType"}
	base.DaoPoolObj.Put("User", base.NewDefaultDao(UserEF(), UserESF(), relationship))
}
